﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Security;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Security.Configuration;
using System.Collections.Specialized;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.Unity;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace Infrastructure.WpfClient.Extensions
{
    [ConfigurationElementType(typeof(CustomAuthorizationProviderData))]
    public class DBAuthorizationProvider : AuthorizationProvider
    {
        [Dependency("AuthorizationCacheManager")]
        public ICacheManager CacheManager { get; set; }

        [Dependency("AuthorizationDB")]
        public Database AuthorizationDB { get; set; }

        public string ApplicationName { get; set; }

        public DBAuthorizationProvider(NameValueCollection configurationItems)
        {
            this.ApplicationName = configurationItems["ApplicationName"]; 
        }
        public override bool Authorize(System.Security.Principal.IPrincipal principal, string context)
        {
            if ( principal == null) return false; 
            if ( principal.Identity == null) return false;
            if (this.CacheManager.Contains(principal.Identity.Name + context))
            {
                return (bool)this.CacheManager.GetData(principal.Identity.Name + context);
            }
            else
            {
                var cmd = this.AuthorizationDB.GetSqlStringCommand("select [Rule] from [SecurityRules] where ActionName=@Name and ApplicationName = @ApplicationName");
                this.AuthorizationDB.AddInParameter(cmd, "Name", System.Data.DbType.String, context);
                this.AuthorizationDB.AddInParameter(cmd, "ApplicationName", System.Data.DbType.String, this.ApplicationName);
                Parser parser = new Parser();
                string expression = (string)this.AuthorizationDB.ExecuteScalar(cmd);
                if (string.IsNullOrEmpty(expression)) return false;
                var result = parser.Parse(expression).Evaluate(principal);
                this.CacheManager.Add(principal.Identity.Name + context, result);  
                return result; 
            }
        }
    }
}
